import logging
import os
from functools import wraps
from flask import Blueprint, request, make_response, Response
from app import app
from app.enums.enums import RoleEnum
from app.models import User
from app.util.result import Result
from app.service.monitor_service import MonitorService

monitor_bp = Blueprint('monitor', __name__)
# 配置日志记录器
logger = logging.getLogger(__name__)


# 定义一个装饰器
def check_power(func):
    @wraps(func)  # 保留被装饰函数的元信息
    def wrapper(*args, **kwargs):
        user_id = app.payload['id']
        user = User.query.filter_by(id=user_id).first()
        if user is None or user.identity != RoleEnum.ADMIN.value:
            return Result.fail("非法行为")
        # 执行原函数
        return func(*args, **kwargs)

    return wrapper


@monitor_bp.route('/baseInfo', methods=['GET'])
@check_power
def base_info():
    """
    获取服务器系统的一些基础信息
    :return: 系统运行时间、活跃用户数、房屋增长点、告警信息数
    """
    user_id = app.payload['id']
    success, message, data = MonitorService.get_system_base_information(user_id)
    if success:
        logger.info("获取系统信息成功")
        return Result.success(message, data)
    else:
        logger.info("获取系统信息失败：" + message)
        return Result.fail(message, data)


@monitor_bp.route('/logs', methods=['GET'])
@check_power
def logs():
    """
    获取系统运行的关键日志
    :return: 日志列表
    """
    user_id = app.payload['id']
    success, message, data = MonitorService.get_system_logs(user_id)
    if success:
        logger.info("获取系统日志成功")
        return Result.success(message, data)
    else:
        logger.info("获取系统日志失败：" + message)
        return Result.fail(message, data)


@monitor_bp.route('/logs', methods=['POST'])
@check_power
def change_logs_remain_days():
    """
    更改日志保留天数
    :return: 成功或失败
    """
    user_id = app.payload['id']
    days = request.get_json()['days']
    success, message = MonitorService.change_logs_remain_days(user_id, days)
    if success:
        logger.info("修改日志保留天数成功")
        return Result.success(data=None)
    else:
        logger.info("修改日志保留天数失败" + message)
        return Result.fail(message)


@monitor_bp.route('/getLogFile', methods=['GET'])
@check_power
def get_log_file():
    """
    获取所有日志文件的元信息
    :return: name,size
    """
    user_id = app.payload['id']
    success, message, data = MonitorService.get_log_file(user_id)
    if success:
        return Result.success(data=data)
    else:
        return Result.fail(message=message)


@monitor_bp.route('/interfaces', methods=['GET'])
@check_power
def get_interfaces():
    """
    获取系统各接口信息，包括请求次数，失败次数，时间
    :return:
    """
    user_id = app.payload['id']
    success, message, data = MonitorService.get_interfaces(user_id)
    if success:
        return Result.success(data=data)
    else:
        return Result.fail(message)

@monitor_bp.route('/logs/download/<path:filename>', methods=['GET'])
@check_power
def download_logs(filename):
    """
    下载日志文件
    :return: 日志文件
    """
    user_id=app.payload['id']
    logger.info(f"管理员{user_id}下载日志文件：{filename}")
    file_path = f'logs/{filename}'
    err_res=make_response()
    try:
        print(f"文件大小: {os.path.getsize(file_path)} 字节")
    except Exception as e:
        print(f"检查文件失败: {e}")
        err_res.status_code=404
        return err_res
    # 检查文件是否可读
    if not os.access(file_path, os.R_OK):
        err_res.status_code=403
        return err_res

    try:
        # 获取文件大小
        file_size = os.path.getsize(file_path)
        print(f"准备下载文件: {file_path}, 大小: {file_size} 字节")

        # 使用 Response 手动返回文件内容
        f=open(file_path, 'rb')
        response = Response(
            f,
            mimetype='application/octet-stream',
            headers={
                'Content-Disposition': f'attachment; filename={filename}',
                'Content-Length': file_size
            }
        )

        # 禁用缓存
        response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
        response.headers['Pragma'] = 'no-cache'
        response.headers['Expires'] = '0'

        return response

    except Exception as e:
        print(f"下载文件出错: {e}")
        err_res.status_code=500
        return err_res